using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Collections.ObjectModel;

namespace Microsoft.PowerShell.CmdletManagement
{
    /// <summary>
    /// Interaction logic for ParameterSetGroupingEditor.xaml
    /// </summary>

    public partial class ParameterSetGroupingEditor : System.Windows.Controls.UserControl
    {
        public ParameterSetGroupingEditor()
        {
            InitializeComponent();
            OnParameterAdded += new ParameterAddedEventHandler(SourceCollection_OnParameterAdded);

            this.IsEnabled = false;
        }

        public List<string> Value
        {
            get { return (List<string>) GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value);  }
        }

        public bool IsReadOnly
        {
            get { return (bool)GetValue(IsReadOnlyProperty); }
            set { SetValue(IsReadOnlyProperty, value); }
        }
        
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(List<string>), typeof(ParameterSetGroupingEditor),
                new FrameworkPropertyMetadata(new List<string>(), new PropertyChangedCallback(OnValueChanged)));

        public delegate void ParameterAddedEventHandler(string newParameter);
        public static event ParameterAddedEventHandler OnParameterAdded;
        public void NotifyParameterAdded(string newParameter)
        {
            if (OnParameterAdded != null)
            {
                OnParameterAdded(newParameter);
            }
        }

        private static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ParameterSetGroupingEditor groupingEditor = d as ParameterSetGroupingEditor;

            if (((bool)e.NewValue) == true)
            {
                groupingEditor.IsEnabled = false;
            }
            else
            {
                groupingEditor.IsEnabled = true;
            }
        }

        public static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(ParameterSetGroupingEditor),
            new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnIsReadOnlyChanged)));

        private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ParameterSetGroupingEditor parameterSetGroupingEditorControl = o as ParameterSetGroupingEditor;
            List<string> newValues = (List<string>) e.NewValue;

            ObservableCollection<ParameterSetSelector> allParameterSets =
                (ObservableCollection<ParameterSetSelector>)parameterSetGroupingEditorControl.ParameterSetsList.ItemsSource;

            // Check if we got a new parameter set
            foreach (string newItem in newValues)
            {
                if ((newItem != null) && (newItem.Trim().Length > 0))
                {
                    ParameterSetSelector comparisonItem = new ParameterSetSelector(false, newItem);

                    if (! allParameterSets.Contains(comparisonItem))
                    {
                        allParameterSets.Add(comparisonItem);
                    }
                }
            }

            // See which ones we need to check
            foreach (ParameterSetSelector item in allParameterSets)
            {
                if (newValues.Contains(item.ParameterSetName))
                {
                    item.IsChecked = true;
                    parameterSetGroupingEditorControl.SpecificSetRadioButton.IsChecked = true;
                }
            }
        }

        private void SourceCollection_OnParameterAdded(string newParameter)
        {
            AddCurentSetNameToList(newParameter, false);
        }

        // They clicked "Add a set"
        private void Click_AddSet(object sender, System.Windows.RoutedEventArgs e)
        {
            NewSetName.Visibility = Visibility.Visible;
            NewSetTitle.Visibility = Visibility.Collapsed;
            NewSetName.Focus();
        }

        // The text box lost focus
        private void LostFocus_NewSet(object sender, System.Windows.RoutedEventArgs e)
        {
            string newSetName = NewSetName.Text;

            if ((newSetName != null) && (newSetName.Trim().Length > 0))
            {
                AddCurentSetNameToList(newSetName, true);
                NotifyParameterAdded(newSetName);
            }
            else
            {
                ResetNewSetUi();
            }
        }

        // They pressed a key
        private void KeyUp_NewSetName(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                string newSetName = NewSetName.Text;

                if ((newSetName == null) || (newSetName.Trim().Length == 0))
                {
                    MessageBox.Show("That parameter set name is invalid.", "Invalid parameter set name");
                    NewSetName.Focus();
                    return;
                }

                AddCurentSetNameToList(newSetName, true);
                NotifyParameterAdded(newSetName);
            }
        }

        public void AddCurentSetNameToList(string setName, bool isChecked)
        {
            ObservableCollection<ParameterSetSelector> parameters = 
                (ObservableCollection<ParameterSetSelector>) ParameterSetsList.ItemsSource;
            ParameterSetSelector newParameterSetItem = new ParameterSetSelector(isChecked, setName);

            if (!parameters.Contains(newParameterSetItem))
            {
                parameters.Add(newParameterSetItem);
                ResetNewSetUi();
            }
        }

        private void ResetNewSetUi()
        {
            NewSetTitle.Visibility = Visibility.Visible;
            NewSet.IsChecked = false;
            NewSetName.Visibility = Visibility.Collapsed;
            NewSetName.Text = "";
        }
    }
}